home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Taifun / Taifun 036 (1987-11-15)(Ossowski, Stefan)(DE)(PD).zip / Taifun 036 (1987-11-15)(Ossowski, Stefan)(DE)(PD).adf / Sol / solx.c < prev   
C/C++ Source or Header  |  1989-01-18  |  14KB  |  690 lines

  1. /*    solx.c - solitare 
  2.       ported to the amiga from unix 4.3bsd
  3.       by Joel Swank 9/22/87
  4. */
  5. #include    <stdio.h>
  6. #include    <ctype.h>
  7. #include    <time.h>
  8. #include    <exec/types.h>
  9. #include    <stat.h>
  10. #include    <libraries/dos.h> 
  11. #include    <functions.h>
  12.  
  13. #undef        TRUE
  14. #undef        FALSE
  15. #define     TRUE    1
  16. #define        FALSE    0
  17.  
  18. int    amode;
  19. int    cnt;
  20. int    cheat;
  21. int    deck[53];
  22. int    ace[4][14];
  23. int    run[7][53];
  24. int    hidden[7][8];
  25. char    cmd[40], *cp;
  26. char    *resgb;
  27.  
  28.  
  29. int    long_run[7];
  30. int    long_hide[7];
  31. int    long_ace[4];
  32. int    base_run[7];
  33.  
  34. extern    struct tm    *localtime();
  35. extern    char        *getenv();
  36. extern    long        time();
  37.  
  38. main(n, a)
  39. char **a;
  40.  {
  41.     int i, p, c, r, s;
  42.     long now;
  43.     struct tm *tp;
  44.     int from;
  45.     int split;
  46.     int dest;
  47.     int brkflg;
  48.  
  49.     amode = 0;
  50.     (void) time(&now);
  51.     tp = localtime(&now);
  52.     srand((unsigned) (tp->tm_sec));
  53.     init();
  54.     for (i = 0; i < 52; i++)
  55.       deck[i] = i;
  56.     deck[52] = -1;
  57.     shuffle(deck);
  58.     for (i = 0; i < 4; i++)
  59.       ace[i][0] = -1;
  60.     for (i = 0; i < 7; i++)
  61.       hidden[i][0] = run[i][0] = -1;
  62.     for (p = 0; p < 7; p++)
  63.       for (c = p; c < 7; c++)
  64.     put(hidden[c],get(deck));
  65.     put(run[0], get(hidden[0]));
  66.     for (r = 1; r < 7; r++)
  67.       for (i = 0; i < 4; i++)
  68.         put(run[r],get(deck));
  69.     redraw(TRUE);
  70.     for (r = 0; r < 7; r++)
  71.      {
  72.     while (getvalue(peek(run[r])) == 0)
  73.      {
  74.         s = getsuit(peek(run[r]));
  75.         put(ace[s],get(run[r]));
  76.         if (run[r][0] == -1)
  77.           put(run[r],get(hidden[r]));
  78.         redraw(FALSE);
  79.      }
  80.      }
  81.     cnt = cheat = 0;
  82.     if (n > 1 && !strcmp(a[1], "auto"))
  83.       autopilot();
  84.     brkflg = 1;
  85.     while (brkflg)
  86.      {
  87.     cnt++;
  88.     do
  89.      {
  90.         moveto(19, 0);
  91.         (void) printf("cmd:%d> ",cnt);
  92.         cleol();
  93.         (void) fflush(stdout);
  94.      } while (!getst(cp = cmd));
  95.     while (*cp == ' ' || *cp == '\t')
  96.       cp++;
  97.     switch (*cp++)
  98.      {
  99.         case 'a':
  100.           autopilot();
  101.         break;
  102.         case 'm':
  103.          {
  104.         while (*cp == ' ' || *cp == '\t')
  105.           cp++;
  106.         if (!(from = *cp++) || from < '1' || from > '7')
  107.          {
  108.             whoops();
  109.             continue;
  110.          }
  111.         while (*cp == ' ' || *cp == '\t')
  112.           cp++;
  113.         for (split = 0; isdigit(*cp); split = split * 10 + *cp++ - '0')
  114.           ;
  115.         if (split < 1 || split > lstlen(run[from - '1']))
  116.          {
  117.             whoops();
  118.             continue;
  119.          }
  120.         while (*cp == ' ' || *cp == '\t')
  121.           cp++;
  122.         if (!(dest = *cp++) || ((dest < '1' || dest > '7') &&
  123.             dest != 'a') || !movecard(from, split, dest, FALSE))
  124.          {
  125.             whoops();
  126.             continue;
  127.          }
  128.         if (ordered())
  129.           finish();
  130.          }
  131.         break;
  132.         case 'h':
  133.         case '?':
  134.           disphelp();
  135.         break;
  136.         case 'r':
  137.           disprules();
  138.         break;
  139.         case 'q':
  140.           brkflg = 0;
  141.         break;
  142.         case 'w':
  143.          {
  144.         while (*cp == ' ' || *cp == '\t')
  145.           cp++;
  146.         if ((from = *cp - '1') < 0 || from > 6)
  147.          {
  148.             whoops();
  149.             continue;
  150.          }
  151.         moveto(21, 0);
  152.         (void) printf("%d cards hidden under run %c:\n", lstlen(hidden[from]),
  153.                                 from + '1');
  154.         for (i = 0; hidden[from][i] != -1; i++)
  155.          {
  156.             pcard(hidden[from][i]);
  157.             (void) putchar(' ');
  158.          }
  159.         (void) printf("\nHit return -");
  160.         (void) fflush(stdout);
  161.         (void) getchar();
  162.         moveto(21, 0);
  163.         cleol();
  164.         (void) putchar('\n');
  165.         cleol();
  166.         cheat++;
  167.          }
  168.         break;
  169.         case 'p':
  170.          {
  171.         while (*cp == ' ' || *cp == '\t')
  172.           cp++;
  173.         if ((from = *cp - '1') < 0 || from > 6)
  174.          {
  175.             whoops();
  176.             continue;
  177.          }
  178.         while (hidden[from][0] != -1)
  179.           put(run[from], get(hidden[from]));
  180.         redraw(FALSE);
  181.         cheat++;
  182.          }
  183.         break;
  184.         case 's':
  185.          {
  186.         while (*cp == ' ' || *cp == '\t')
  187.           cp++;
  188.         if ((from = *cp - '1') < 0 || from > 6)
  189.          {
  190.             whoops();
  191.             continue;
  192.          }
  193.         shuffle(run[from]);
  194.         long_run[from] = -1;
  195.         redraw(FALSE);
  196.         cheat++;
  197.          }
  198.         break;
  199.         default:
  200.           whoops();
  201.         break;
  202.      }
  203.      }
  204.     moveto(21, 0);
  205.     cleol();
  206.     (void) printf("I see you gave up\n");
  207.     if (cheat > 0)
  208.       (void) printf("    ... even after you cheated %d times!\n", cheat);
  209.     else
  210.       (void) printf("    ... but at least you didn't cheat...congratulations!\n");
  211.     unwind(0);
  212.  }
  213.  
  214. unwind(ret)
  215.  {
  216.     moveto(23, 0);
  217.     deinit();
  218.     exit(ret);
  219.  }
  220.  
  221. movecard(from, split, dest, limitmove)
  222.  {
  223.     if (from == dest)
  224.       return(FALSE);
  225.     return(dest == 'a' ? run2ace(from) : run2run(from, split, dest, limitmove));
  226.  }
  227.  
  228. run2ace(from)
  229.  {
  230.     int fcard, s, ok;
  231.  
  232.     fcard = peek(run[from -= '1']);
  233.     if (ok = getvalue(peek(ace[s = getsuit(fcard)])) == getvalue(fcard) - 1)
  234.      {
  235.     put(ace[s], get(run[from]));
  236.     redraw(FALSE);
  237.     tidy(from);
  238.      }
  239.     return(ok);
  240.  }
  241.  
  242. run2run(from, split, dest, limitmove)
  243.  {
  244.     int fcard, dcard, i, ok;
  245.  
  246.     if ((fcard = run[from -= '1'][--split]) == -1)
  247.       return(FALSE);
  248.     dcard = peek(run[dest -= '1']);
  249.     if (amode > 0 && dcard == -1 && getvalue(fcard) == 12 &&
  250.                         lstlen(hidden[from]) == 0)
  251.       return(FALSE);
  252.     if (amode > 0 && limitmove && split && chk2run(fcard, run[from][split - 1]))
  253.       return(FALSE);
  254.     if (ok = chk2run(fcard, dcard))
  255.      {
  256.     for (i = split; run[from][i] != -1; i++)
  257.       put(run[dest], run[from][i]);
  258.     run[from][split] = -1;
  259.     redraw(FALSE);
  260.     tidy(from);
  261.      }
  262.     return(ok);
  263.  }
  264.  
  265. tidy(from)
  266.  {
  267.     int s;
  268.  
  269.     while (getvalue(peek(run[from])) == 0)
  270.      {
  271.     s = getsuit(peek(run[from]));
  272.     put(ace[s],get(run[from]));
  273.     redraw(FALSE);
  274.      }
  275.     if (lstlen(hidden[from]) != 0 && lstlen(run[from]) == 0)
  276.      {
  277.     while (getvalue(peek(hidden[from])) == 0)
  278.      {
  279.         s = getsuit(peek(hidden[from]));
  280.         put(ace[s],get(hidden[from]));
  281.         redraw(FALSE);
  282.      }
  283.     put(run[from],get(hidden[from]));
  284.     redraw(FALSE);
  285.      }
  286.  }
  287.  
  288. chk2run(fcard,dcard)
  289.  {
  290.     if (dcard == -1 && getvalue(fcard) == 12)
  291.       return(TRUE);
  292.     return(getvalue(dcard) - 1 == getvalue(fcard) &&
  293.                 getcolour(dcard) != getcolour(fcard));
  294.  }
  295.  
  296. ordered()
  297.  {
  298.     int i, j;
  299.  
  300.     for (i = 0; i < 7; i++)
  301.       if (hidden[i][0] != -1)
  302.     return(FALSE);
  303.       else if (run[i][0] != -1)
  304.     for (j = 1; run[i][j] != -1; j++)
  305.       if (getvalue(run[i][j]) != getvalue(run[i][j - 1]) - 1 ||
  306.             getcolour(run[i][j]) == getcolour(run[i][j - 1]))
  307.         return(FALSE);
  308.     return(TRUE);
  309.  }
  310.  
  311. cardsleft()
  312.  {
  313.     int i;
  314.     for (i = 0; i < 7; i++)
  315.       if (run[i][0] != -1)
  316.     return(TRUE);
  317.     return(FALSE);
  318.  }
  319.  
  320. finish()
  321.  {
  322.     int i;
  323.  
  324.     moveto(21, 0);
  325.     (void) printf("\007I'll finish for you now\007");
  326.     (void) fflush(stdout);
  327.     do
  328.       for (i = 0; i < 7; i++)
  329.     while (movecard(i + '1', 0, 'a', FALSE))
  330.       ;
  331.      while (cardsleft());
  332.     moveto(21, 40);
  333.     cleol();
  334.     (void) printf("\007You WIN\007\n");
  335.     if (cheat > 0)
  336.       (void) printf("    ... but you cheated %d times!", cheat);
  337.     else
  338.       (void) printf("    ... and without cheating ... congratulations!");
  339.     unwind(0);
  340.  }
  341.  
  342. autopilot()
  343.  {
  344.     int i, j, k, l, ret;
  345.  
  346.     moveto(21, 0);
  347.     (void) printf("Going into automatic mode...");
  348.     (void) fflush(stdout);
  349.     amode = TRUE;
  350.     do
  351.      {
  352.     l = 0;
  353.     for (i = 0; i < 7; i++)
  354.       for (j = 0; j < 7; j++)
  355.         for (k = 0; k < lstlen(run[i]); k++)
  356.           l = movecard(i + '1', k+1, j + '1', TRUE) || l;
  357.     for (i = 0; i < 7; i++)
  358.       l = movecard(i + '1', 0, 'a', FALSE) || l;
  359.      } while (l);
  360.     moveto(21, 28);
  361.     if (!cardsleft())
  362.      {
  363.     (void) printf("\007YEA...\007");
  364.     (void) fflush(stdout);
  365.     for (i = 0; i < 7; i++)
  366.       if (movecard(i + '1', 0, 'a', FALSE))
  367.     moveto(21, 34);
  368.     (void) printf("I won!!!!!");
  369.      ret=0;
  370.      }
  371.     else
  372.       {
  373.       (void) printf("I couldn't win this time");
  374.       ret=1;
  375.       }
  376.     unwind(ret);
  377.  }
  378.  
  379. redraw(display)
  380.  {
  381.     int i, j;
  382.  
  383.     if (display)
  384.      {
  385.     clear();
  386.     for (i = 0; i < 7; i++)
  387.      {
  388.         long_run[i] = long_hide[i] = base_run[i] = -1;
  389.         moveto(i + i + 2, 1);
  390.         (void) putchar(i + '1');
  391.      }
  392.     moveto(0, 6);
  393.     for (i = 1; i < 21; i++)
  394.       (void) printf("%3d", i);
  395.     for (i = 0; i < 4; i++)
  396.       long_ace[i] = -1;
  397.     moveto(17, 1);
  398.     (void) printf("ACES:");
  399.      }
  400.     for (i = 0; i < 7; i++)
  401.      {
  402.     if (long_hide[i] != lstlen(hidden[i]))
  403.      {
  404.         moveto(i + i + 2, 4);
  405.         (void) putchar(lstlen(hidden[i]) ? lstlen(hidden[i]) + '0' : ' ');
  406.         long_hide[i] = lstlen(hidden[i]);
  407.      }
  408.      }
  409.     for (i = 0; i < 4; i++)
  410.      {
  411.     if (long_ace[i] != lstlen(ace[i]))
  412.      {
  413.         moveto(17, 8 + i * 5);
  414.         if (ace[i][0] != -1)
  415.           pcard(peek(ace[i]));
  416.         else
  417.           (void) printf("--");
  418.         long_ace[i] = lstlen(ace[i]);
  419.      }
  420.      }
  421.     for (i = 0; i < 7; i++)
  422.      {
  423.     if (long_run[i] != lstlen(run[i]) ||
  424.                 (long_run[i] == 1 && base_run[i] != run[i][0]))
  425.      {
  426.         moveto(i + i +  2, 7);
  427.         for (j = 0; run[i][j] != -1; j++)
  428.          {
  429.         if (run[i][j] == -1)
  430.           (void) printf("  ");
  431.         else
  432.           pcard(run[i][j]);
  433.         (void) putchar(' ');
  434.          }
  435.         while (j++ < long_run[i])
  436.           (void) printf("   ");
  437.         long_run[i] = lstlen(run[i]);
  438.         base_run[i] = run[i][0];
  439.      }
  440.      }
  441.     (void) fflush(stdout);
  442.     (void) Delay(10L);
  443.  }
  444.  
  445. pcard(card)
  446.  {
  447.     int i;
  448.  
  449.     if ((i = getcolour(card)) != 0)
  450.       standout();
  451.     (void) printf("%c%c", "A23456789TJQK"[getvalue(card)], "HDSC"[getsuit(card)]);
  452.     if (i)
  453.       standend();
  454.  }
  455.  
  456. getvalue(card)
  457.  {
  458.     return(card % 13);
  459.  }
  460.  
  461. getsuit(card)
  462.  {
  463.     return(card / 13);
  464.  }
  465.  
  466. getcolour(card)
  467.  {
  468.     return(card / 26);
  469.  }
  470.  
  471. whoops()
  472.  {
  473.     moveto(19, 0);
  474.     (void) printf("\007Invalid Command: '%s'\007", cmd);
  475.     (void) fflush(stdout);
  476.     (void) Delay(40L);
  477.  }
  478.  
  479. disphelp()
  480.  {
  481.     clear();
  482.     (void) printf("\
  483. Commands: m [1-7] [pos] [1-7a] : move cards or runs\n\
  484.           a                    : turn on the auto pilot\n\
  485.           s [1-7]              : shuffle the cards in a run (cheat!)\n\
  486.           p [1-7]              : put a hidden pile onto the run (cheat!)\n\
  487.           w [1-7]              : print the cards in a hidden pile (cheat!)\n\
  488.           h or ?               : print this command summary\n\
  489.           r                    : print the rules of the game\n\
  490.           q                    : quit\n\n");
  491.     (void) printf("\
  492. Moving:   There are three parameters in the m command: the first is the\n\
  493.           run to be moved from, the second is the card number to split\n\
  494.           the run at (check numbers along the top), and the third is\n\
  495.       the destination run (or 'a' if an ace pile). Since only one card\n\
  496.       can be moved to an ace at a time, the pos paramter is ignored\n\
  497.       in this case. To give a couple of examples 'm 6 1 4 would move\n\
  498.       all cards from run 6 to run 4, and m 3 5 7 would split run 3\n\
  499.       before the fifth card (leaving 4) and move the rest to run 7.\n\n\
  500. Cheating: Commands that allow cheating are available but they will count\n\
  501.           against you in your next life!\n\n\nHit Return -");
  502.     (void) fflush(stdout);
  503.     (void) getchar();
  504.     redraw(TRUE);
  505.  }
  506.  
  507. disprules()
  508.  {
  509.     clear();
  510.     (void) printf("\
  511. Object:   The object of this game is to get all of the cards in each suit\n\
  512.           in order on the proper ace pile.\n\n\
  513. Rules:    Cards are played on the ace piles in ascending order: A,2,...,K.\n\
  514.           All aces are automatically placed in the correct aces pile as\n\
  515.           they're uncovered in runs or from a pile of hidden cards. Once a\n\
  516.           card is placed in an ace pile it can't be removed.\n\n");
  517.     (void) printf("\
  518.           When moving runs, they can be split anywhere, but the top card\n\
  519.       in the run moved must be placed on a card one higher (i.e. 5 on\n\
  520.       a 6) and always on a card of the opposite color.\n\n");
  521.     (void) printf("\
  522.           Whenever a whole run is moved, the top hidden card is turned\n\
  523.           over, thus becoming the beginning of a new run.  If there are no\n\
  524.           hidden cards left, a space is created which can only be filled by\n\
  525.           a king.\n\n\nHit Return -");
  526.     (void) fflush(stdout);
  527.     (void) getchar();
  528.     redraw(TRUE);
  529.  }
  530.  
  531. getst(getbuf)
  532. char *getbuf;
  533.  {
  534.     int ch;
  535.     int nc;
  536.  
  537.     *(resgb = getbuf) = nc = 0;
  538.     for (;;)
  539.      {
  540.     if ((((ch = getchar()) >= ' ' && ch <= '~') || ch == '\t') && nc < 40)
  541.      {
  542.         *getbuf++ = ch;
  543.         *getbuf = 0;
  544.         nc++;
  545.         (void) putchar(ch);
  546.         (void) fflush(stdout);
  547.      }
  548.     else if (ch == '\b')
  549.      {
  550.         if (nc--)
  551.          {
  552.             *--getbuf = 0;
  553.         (void) printf("\b \b");
  554.         (void) fflush(stdout);
  555.          }
  556.         else
  557.           return(FALSE);
  558.      }
  559.     else if (ch == ('r' & 0x1f))
  560.       redraw(TRUE);
  561.     else if (ch == '\r')
  562.       return(TRUE);
  563.      }
  564.  }
  565.  
  566. shuffle(cards)
  567. int *cards;
  568.  {
  569.     int i, j, k, t;
  570.  
  571.     for (i = 0; cards[i] != -1; i++)
  572.       ;
  573.     if (i)
  574.      {
  575.     for (j = 0; j < i; j++)
  576.      {
  577.         do
  578.           k = rnd(i);
  579.          while (k == j);
  580.         t = cards[j];
  581.         cards[j] = cards[k];
  582.         cards[k] = t;
  583.      }
  584.      }
  585.  }
  586.  
  587. rnd(n)
  588.  {
  589.     return(((rand() >> 12 | rand() >> 6) & (unsigned) ~0 >> 1) % n);
  590.  }
  591.  
  592. lstlen(list)
  593. int *list;
  594.  {
  595.     int i;
  596.  
  597.     for (i = 0; list[i] != -1; i++)
  598.       ;
  599.     return(i);
  600.  }
  601.  
  602. xputc(c)
  603. register c;
  604.  {
  605.     (void) putchar(c);
  606.  }
  607.  
  608. init()
  609.  {
  610.  printf("\033\143");
  611.  printf("\233H\233J");
  612.  set_raw();
  613.  }
  614.  
  615. deinit()
  616.  {
  617.  set_con();
  618.  }
  619.  
  620. clear()
  621.  {
  622.  printf("\233H\233J");
  623.  }
  624.  
  625. cleol()
  626.  {
  627.     printf("\233K");
  628.  }
  629.  
  630. standout()
  631.  {
  632.     putchar('\233');
  633.     printf("42m");
  634.  }
  635.  
  636. standend()
  637.  {
  638.     putchar('\233');
  639.     printf("40m");
  640.  }
  641.  
  642. moveto(y, x)
  643.  {
  644.     printf("\233%d;%dH",(y)+1,(x));
  645.  }
  646.  
  647.  
  648. put(dest, item)
  649. int *dest;
  650.  {
  651.     if (item == -1)
  652.       return;
  653.     while (*dest != -1)
  654.       dest++;
  655.     *dest++ = item;
  656.     *dest = -1;
  657.  }
  658.  
  659. get(source)
  660. int *source;
  661.  {
  662.     int i;
  663.  
  664.     for (i = 0; *source != -1; i++, source++)
  665.       ;
  666.     if (i)
  667.      {
  668.     i = *--source;
  669.     *source = -1;
  670.     return(i);
  671.      }
  672.     return(-1);
  673.  }
  674.  
  675. peek(source)
  676. int *source;
  677.  {
  678.     int i;
  679.  
  680.     for (i = 0; source[i] != -1; i++)
  681.       ;
  682.     return(i ? source[i - 1] : -1);
  683.  }
  684.  
  685. _abort()
  686. {
  687.     (void) getchar();
  688.     unwind(0);
  689. }
  690.